﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.IO;
using System.Reflection;
using Office = Microsoft.Office.Core;
using VBIDE = Microsoft.Vbe.Interop;
using Excel = Microsoft.Office.Interop.Excel;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using Microsoft.Vbe.Interop;
namespace CreateMacro
{

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            label3.Visible = false;
        }
        [DllImport("user32.dll")]
        public static extern bool LockWindowUpdate(IntPtr hWndLock);
        public Regex keyWords = new Regex("AddHandler|AndAlso|Byte|Catch|CDate|CInt|Const|CSng|CULng|Declare|DirectCast|Else|Enum|Exit|Friend|GetXMLNamespace|Handles|Imports (.NET Namespace and Type)|Integer|Let|Loop|MustInherit|Namespace|Not|Object|Option|Overloads|Partial|Public|REM|SByte|Shared|Step|Sub|To|TypeOf|ULong|While|WriteOnly|#ElseIf" +
            "#End|Xor|Widening|UShort|True|SyncLock|Stop|Short|Select|RemoveHandler|RaiseEvent|Private|Overridable|Optional|Of|Nothing|Narrowing|MustOverride|Me|Lib|Interface|Imports|If|Global|Function|False|Erase|ElseIf|Do|Default|CUShort|CStr|Continue|Class|CDec|CBool|ByVal|As|AddressOf" +
            "Alias|Boolean|Call|CByte|CDbl|CLng|CSByte|CType|Date|Delegate|Double|End|Error|Finally|Get|GoSub|If()|In|Is|Like|Mod|MyBase|New|NotInheritable|On|Or|Overrides|Property|ReadOnly|Resume|Set|Single|String|Then|Try|Wend|Using|With|#Const|#If" +
            "#Else|WithEvents|When|UInteger|TryCast|Throw|Structure|Static|Shadows|Return|ReDim|Protected|ParamArray|Operator|OrElse|NotOverridable|Next|MyClass|Module|Long|IsNot|Inherits|Implements|GoTo|GetType|ForEvent|EndIf|Each|Dim|Decimal|CUInt|CShort|CObj|Char|CChar|Case|ByRef|And|");
        private string[] lines;
        private List<KeyValuePair<String, String>> lst = new List<KeyValuePair<string, string>>();
        private List<KeyValuePair<String, String>> lstError = new List<KeyValuePair<string, string>>();
        private string filepath = "";
        private int index = 0;
        private bool error = false;
        private void createMacro(List<KeyValuePair<String, String>> list)
        {
            foreach (var items in list)
            {
                label3.Text = items.Value;
                string Files = items.Value;
                try
                {

                    Excel.Application oExcel;
                    Excel.Workbook oBook;
                    VBIDE.VBComponent oModule;
                    String sCode;
                    Object oMissing = System.Reflection.Missing.Value;
                    oExcel = new Excel.Application();
                    oBook = oExcel.Workbooks.Add(oMissing);
                    bool IsPass = oBook.HasPassword;
                    if (!IsPass)
                    {
                        oExcel.DisplayAlerts = false;
                        oBook = oExcel.Workbooks.Open(Files, false, true, Type.Missing, string.Empty, string.Empty, true, Type.Missing, Type.Missing, false, false, Type.Missing, false, true, Type.Missing);
                    }
                    else
                    {
                        oBook = oExcel.Workbooks.Open(Files, false, true, Type.Missing, Type.Missing, Type.Missing, true, Type.Missing, Type.Missing, false, false, Type.Missing, false, true, Type.Missing);
                    }
                    try
                    {
                        oModule = oBook.VBProject.VBComponents.Add(VBIDE.vbext_ComponentType.vbext_ct_StdModule);
                        sCode = rtxSource.Text;
                        oModule.CodeModule.AddFromString(sCode);
                    }
                    catch
                    {
                        error = true;
                        foreach (var lstitem in lst)
                        {
                            lstError.Add(lstitem);
                        }
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook);
                        oExcel.Quit();
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel);
                        GC.Collect();
                        MessageBox.Show(" Excel cần được thiết lập để sử dụng tool");
                        return;
                    }
                    object misValue = System.Reflection.Missing.Value;
                    string name = Path.GetFileName(Files);
                    filepath = textBox3.Text + @"\" + name.Substring(0, name.LastIndexOf(".")) + ".xls";
                    if (File.Exists(filepath))
                    {
                        File.Delete(filepath);
                    }
                    oBook.SaveAs(filepath, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);

                    System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook);
                    oExcel.Quit();
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel);
                    GC.Collect();
                    if (File.Exists(Files))
                    {
                        File.Delete(Files);
                    }

                }
                catch
                {

                    lstError.Add(new KeyValuePair<String, String>(Files.Substring(Files.LastIndexOf("\\") + 1), Files));
                }
            }
          
        }
        private void button1_Click(object sender, EventArgs e)
        {
            error = false;
            if (rtxSource.Text == "")
            {
                MessageBox.Show("Kiểm tra lại mã Macro !!!");
                return;
            }
            if (lst.Count > 0 && textBox3.Text == "")
            {
                MessageBox.Show("Kiểm tra lại thư mục đích!!!");
                return;
            }
            enabletext(false);
            label3.Visible = true;
            label3.Text = DateTime.Now.ToLongDateString();
          

                if (lstError.Count > 0)
                {
                    lstError.Clear();
                    GetListFile(textBox2.Text);
                }

                createMacro(lst);
                lst.Clear();
                if (lstError.Count > 0)
                {
                    // lstError.RemoveAt(lstError.Count - 1);
                    listFile.Items.Clear();
                    index = 0;
                    foreach (var file in lstError)
                    {
                        ListViewItem item = new ListViewItem((index + 1).ToString());
                        item.SubItems.Add(file.Value);
                        listFile.Items.Add(item);
                        index++;
                    }
                    if (error == false)
                    {
                        MessageBox.Show("Xảy ra lỗi, bạn cần kiểm tra các file trong danh sách đã được đóng !!!!");
                    }

                }
                else
                {
                    listFile.Items.Clear();

                    MessageBox.Show("Hoàn Tất !!!! ");
                }
           
            enabletext(true);
            label3.Text = DateTime.Now.ToLongDateString();

        }
      
        private void enabletext(bool b)
        {
            textBox1.Enabled = b;
            textBox2.Enabled = b;
            rtxSource.Enabled = b;
            textBox3.Enabled = b;
        }

        private void textBox1_MouseDown(object sender, MouseEventArgs e)
        {
          
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "Text Files (.txt)|*.txt";
            openFileDialog1.Title = "Chọn File Macro";
            openFileDialog1.ShowDialog();
            var file = openFileDialog1.FileName;
            textBox1.Text = file;
            string core = "";
            if (File.Exists(file))
            {
                lines = File.ReadAllLines(file);
                foreach (var items in lines)
                {
                    core += items.ToString() + "\r\n";
                }
                rtxSource.Text = core;
            }
            hightlight();
           
        }
     
        private void textBox2_MouseClick(object sender, MouseEventArgs e)
        {
            string curPath = Directory.GetCurrentDirectory();
            fBDDataFolder.SelectedPath = "";
            DialogResult result = fBDDataFolder.ShowDialog();
            if (result == DialogResult.OK)
            {
                textBox2.Text = fBDDataFolder.SelectedPath;
            }
            Directory.SetCurrentDirectory(curPath);
            index = 0;
            listFile.Items.Clear();
            GetListFile(textBox2.Text);
        }
        private void GetListFile(string path)
        {
            //lst.Clear();
            try
            {
                string[] files;
                string[] directories;
                files = Directory.GetFiles(path);

                foreach (string file in files)
                {
                    if ((file.EndsWith(".xls") || file.EndsWith(".xlsx")) && !file.Contains("~") )
                    {
                        ListViewItem item = new ListViewItem((index + 1).ToString());
                        item.SubItems.Add(file);
                        item.SubItems.Add(path.Substring(path.LastIndexOf("\\") + 1));
                        listFile.Items.Add(item);
                        lst.Add(new KeyValuePair<String, String>(path.Substring(path.LastIndexOf("\\") + 1), file));
                        index++;
                    }

                }
                directories = Directory.GetDirectories(path);
                foreach (string directory in directories)
                {
                    // Process each directory recursively
                    GetListFile(directory);
                }
            }
            catch (Exception ex)
            {

            }
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            rtxSource.Text = "";
        }


        private void hightlight()
        {
            try
            {
                LockWindowUpdate(rtxSource.Handle);
                int selPos = rtxSource.SelectionStart;
                foreach (Match keyWordMatch in keyWords.Matches(rtxSource.Text))
                {
                    rtxSource.Select(keyWordMatch.Index, keyWordMatch.Length);
                    rtxSource.SelectionColor = Color.Blue;
                    rtxSource.SelectionStart = selPos;
                    rtxSource.SelectionColor = Color.Black;
                }
            }
            finally { LockWindowUpdate(IntPtr.Zero); }
        }

        private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            
            hightlight();
           
        }

        private void textBox3_Click(object sender, EventArgs e)
        {
            string curPath = Directory.GetCurrentDirectory();
            fBDDataFolder.SelectedPath = "";
            DialogResult result = fBDDataFolder.ShowDialog();
            if (result == DialogResult.OK)
            {
                textBox3.Text = fBDDataFolder.SelectedPath;
            }
            Directory.SetCurrentDirectory(curPath);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            testMacro frm = new testMacro(textBox1.Text);
            frm.Show();
        }

    }
}
